#ifndef BASE_CTF_RULES_H
#define BASE_CTF_RULES_H

#include <concrete/EventSystem.h>

//Added events
//----------------------------------

//Raised by some source of input (e.g., physical, AI, network)
class PlayerControlEvent : public RegisteredClientEvent<PlayerControlEvent>
{
public:
	enum ControlType {
		START,
		STOP,
		TOGGLE
	};
private:
	PlayerEntity* m_pPlayerEntity;
	ControlType m_iControlType;
	String m_sControlName;
public:
	PlayerControlEvent( PlayerEntity* pPlayerEntity, ControlType iControlType,
	                                                       String sControlName )
	 : m_pPlayerEntity( pPlayerEntity ), m_iControlType( iControlType ),
	                                           m_sControlName( sControlName ) {}
	
	PlayerEntity* getPlayerEntity() const { return m_pPlayerEntity; }
	ControlType   getControlType() const { return m_iControlType; }
	String        getControlName() const { return m_sControlName; }
	
	//TODO: Fill this in (needs network encode() and decode() functions)
};

//----------------------------------

//This does the actual application of player control
class PlayerControlResponse : public ResponseTo< PlayerControlEvent >
{
	
public:
	virtual void respond( const PlayerControlEvent& event )
	{
		String sControlName = event.getControlName();
		PlayerEntity* pEntity = event.getPlayerEntity();
		bool& bControl = pEntity->getVar<bool>( sControlName );
		
		typedef PlayerControlEvent PCE;
		switch ( event.getControlType() ) {
			case PCE::START:
				bControl = true;
				break;
			case PCE::END:
				bControl = false;
				break;
			case PCE:TOGGLE:
				bControl = !bControl;
				break;
			default:
				std::cerr << "Error in PlayerControlResponse::respond( ): \
Control is of unknown type ("
                          << event.getControlType()
						  << "). Should be START, END or TOGGLE. Bailing."
						  << std::endl;
				break;
		}
	}
	
};

//At the moment, this binds physical input to PlayerControlEvents
//TODO: Consider changing the name of this class
class PlayerController : public RuleSet
{
public:
	virtual String getID() const { return "PlayerController"; }
	
	virtual std::list< String > getDependencies() const
	{
		std::list< String > sDependencies;
		
		//sDependancies.push_back( "a required RuleSet name" );
		//sDependancies.push_back( "another required RuleSet name" );
		
		return sDependencies;
	}
	
	virtual void addRulesTo( EventManager* pEventMgr )
	{
		//TODO: Read key bindings from settings
		
		//This binds InputEvents to PlayerControlEvents according to the game's
		// key-bindings.
		pEventMgr->addRule( InputEvent( 'A', "down" ),
		                 EventToEventResponse( PlayerControlEvent(START, "moveLeft") ) );
		
	}
};

#endif //BASE_CTF_RULES_H
